#ifndef INPUTOUTPUTHANDLER_H
#define INPUTOUTPUTHANDLER_H

#include "systemCallHandler.h"
#include <QTextEdit>
#include <QInputDialog>
#include <QApplication>
#include <QQueue>
#include <QTimer>
#include <QMutex>

/**
 * @brief 输出格式枚举
 */
enum class OutputFormat {
    PlainText,      // 普通文本
    HtmlText,       // HTML格式文本
    RichText        // 富文本格式
};

/**
 * @brief 输入输出处理器类
 * 
 * 处理所有输入输出相关的系统调用，包括字符、字符串、数字的输入输出，
 * 以及屏幕控制、格式化输出等功能。
 * 支持的中断号范围：0x20-0x2F
 */
class InputOutputHandler : public SystemCallHandler
{
    Q_OBJECT

public:
    explicit InputOutputHandler(QObject *parent = nullptr);
    ~InputOutputHandler() override;

    // 重写基类虚函数
    SystemCallResult handleInterrupt(int interruptNumber, CpuSimulator* cpu) override;
    QPair<int, int> getSupportedInterruptRange() const override;
    QString getDescription() const override;
    void reset() override;

    /**
     * @brief 设置输出控件
     * @param outputWidget 输出文本控件指针
     */
    void setOutputWidget(QTextEdit* outputWidget);

    /**
     * @brief 设置输入模式
     * @param synchronous 是否为同步输入模式
     */
    void setInputMode(bool synchronous);

public slots:
    /**
     * @brief 处理用户输入
     * @param input 用户输入的文本
     */
    void handleUserInput(const QString& input);

private:
    /**
     * @brief INT 0x20 - 字符输出
     * 参数：AX=字符ASCII码
     * 返回：AX=输出状态（0=成功）
     */
    SystemCallResult handleCharacterOutput(CpuSimulator* cpu);

    /**
     * @brief INT 0x21 - 字符串输出
     * 参数：AX=字符串地址
     * 返回：AX=输出字符数
     */
    SystemCallResult handleStringOutput(CpuSimulator* cpu);

    /**
     * @brief INT 0x22 - 整数输出
     * 参数：AX=整数值, BX=进制（2,8,10,16）
     * 返回：AX=输出字符数
     */
    SystemCallResult handleIntegerOutput(CpuSimulator* cpu);

    /**
     * @brief INT 0x23 - 格式化输出
     * 参数：AX=格式字符串地址, BX=参数数组地址
     * 返回：AX=输出字符数
     */
    SystemCallResult handleFormattedOutput(CpuSimulator* cpu);

    /**
     * @brief INT 0x24 - 字符输入
     * 返回：AX=字符ASCII码
     */
    SystemCallResult handleCharacterInput(CpuSimulator* cpu);

    /**
     * @brief INT 0x25 - 字符串输入
     * 参数：AX=缓冲区地址, BX=最大长度
     * 返回：AX=实际输入长度
     */
    SystemCallResult handleStringInput(CpuSimulator* cpu);

    /**
     * @brief INT 0x26 - 整数输入
     * 参数：AX=进制（2,8,10,16）
     * 返回：BX=整数值, AX=状态码
     */
    SystemCallResult handleIntegerInput(CpuSimulator* cpu);

    /**
     * @brief INT 0x27 - 清屏操作
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleClearScreen(CpuSimulator* cpu);

    /**
     * @brief INT 0x28 - 设置光标位置
     * 参数：AX=行号, BX=列号
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleSetCursorPosition(CpuSimulator* cpu);

    /**
     * @brief INT 0x29 - 设置文本颜色
     * 参数：AX=前景色, BX=背景色
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleSetTextColor(CpuSimulator* cpu);

    /**
     * @brief INT 0x2A - 设置输出格式
     * 参数：AX=格式类型
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleSetOutputFormat(CpuSimulator* cpu);

    /**
     * @brief INT 0x2B - 输出换行
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleNewLine(CpuSimulator* cpu);

    /**
     * @brief INT 0x2C - 输出制表符
     * 参数：AX=制表符数量
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleTab(CpuSimulator* cpu);

    /**
     * @brief INT 0x2D - 蜂鸣器
     * 参数：AX=频率, BX=持续时间(毫秒)
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleBeep(CpuSimulator* cpu);

    /**
     * @brief INT 0x2E - 获取按键状态
     * 参数：AX=键码
     * 返回：AX=按键状态（1=按下, 0=未按下）
     */
    SystemCallResult handleGetKeyState(CpuSimulator* cpu);

    /**
     * @brief INT 0x2F - 等待按键
     * 返回：AX=按键ASCII码
     */
    SystemCallResult handleWaitForKey(CpuSimulator* cpu);

    // 辅助方法

    /**
     * @brief 从内存中读取字符串
     * @param cpu CPU模拟器指针
     * @param address 字符串地址
     * @return QString 读取的字符串
     */
    QString readStringFromMemory(CpuSimulator* cpu, int address);

    /**
     * @brief 向内存写入字符串
     * @param cpu CPU模拟器指针
     * @param address 目标地址
     * @param str 字符串
     * @param maxLength 最大长度
     * @return int 实际写入长度
     */
    int writeStringToMemory(CpuSimulator* cpu, int address, const QString& str, int maxLength = -1);

    /**
     * @brief 将整数转换为指定进制的字符串
     * @param value 整数值
     * @param radix 进制（2,8,10,16）
     * @return QString 转换后的字符串
     */
    QString integerToString(int value, int radix);

    /**
     * @brief 将字符串转换为指定进制的整数
     * @param str 字符串
     * @param radix 进制（2,8,10,16）
     * @param ok 转换是否成功
     * @return int 转换后的整数
     */
    int stringToInteger(const QString& str, int radix, bool* ok = nullptr);

    /**
     * @brief 处理格式化字符串
     * @param format 格式字符串
     * @param args 参数数组
     * @return QString 格式化后的字符串
     */
    QString processFormattedString(const QString& format, const QList<int>& args);

    /**
     * @brief 输出文本到控件
     * @param text 要输出的文本
     * @param useCurrentFormat 是否使用当前格式设置
     */
    void outputText(const QString& text, bool useCurrentFormat = true);

    /**
     * @brief 应用颜色格式
     * @param text 原始文本
     * @return QString 应用格式后的文本
     */
    QString applyColorFormat(const QString& text);

    /**
     * @brief 获取用户输入（同步方式）
     * @param prompt 提示信息
     * @param inputType 输入类型（0=字符, 1=字符串, 2=整数）
     * @param radix 整数进制（仅当inputType=2时有效）
     * @return QString 用户输入
     */
    QString getUserInputSync(const QString& prompt, int inputType, int radix = 10);

    /**
     * @brief 验证进制参数
     * @param radix 进制值
     * @return bool 是否有效
     */
    bool isValidRadix(int radix);

private:
    QTextEdit* outputWidget;                    // 输出控件指针
    QString outputBuffer;                       // 输出缓冲区
    bool synchronousInput;                      // 是否为同步输入模式
    OutputFormat currentOutputFormat;           // 当前输出格式
    QString currentForegroundColor;             // 当前前景色
    QString currentBackgroundColor;             // 当前背景色
    int foregroundColor;                        // 前景色代码
    int backgroundColor;                        // 背景色代码
    int cursorRow;                              // 光标行位置
    int cursorColumn;                           // 光标列位置
    
    // 异步输入相关
    QQueue<QString> inputQueue;                 // 输入队列
    QMutex inputMutex;                          // 输入队列互斥锁
    bool waitingForInput;                       // 是否正在等待输入
    
    // 颜色映射表
    static const QMap<int, QString> colorMap;   // 颜色代码到颜色名称的映射
    
    // 常量定义
    static const int MAX_STRING_LENGTH = 1024;  // 最大字符串长度
    static const int MAX_FORMAT_ARGS = 16;      // 最大格式参数数量

signals:
    /**
     * @brief 请求用户输入信号
     * @param prompt 提示信息
     */
    void inputRequested(const QString& prompt);

    /**
     * @brief 蜂鸣器信号
     * @param frequency 频率
     * @param duration 持续时间
     */
    void beepRequested(int frequency, int duration);
};

#endif // INPUTOUTPUTHANDLER_H 